package cn.xiaopengstack.types.framework.strategy.link.mutilModel;

import java.util.Objects;

/**
 * @author jiangyangang
 */
public class LinkedList<E> implements ILink<E>{

    private String name;

    transient int size = 0;

    transient Node<E> first;

    transient Node<E> last;

    public LinkedList(String name) {
        this.name = name;
    }

    /**
     * 连接到第一个元素
     * @param e
     */
    void linkFirst(E e){
        final Node<E> f = first;
        Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null) {
            last = newNode;
        } else {
            f.prev = newNode;
        }

        size++;
    }

    void linkLast(E e){
        final Node<E> l = last;
        Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (Objects.isNull(l)) {
            first = newNode;
        } else {
            l.next = newNode;
        }

        size++;
    }

    @Override
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    @Override
    public boolean addFirst(E e) {
        linkFirst(e);
        return true;
    }

    @Override
    public boolean addLast(E e) {
        linkLast(e);
        return true;
    }

    @Override
    public boolean remove(Object o) {
        if (Objects.isNull(o)) {
            for (Node<E> x = first; x != null; x = x.next){
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next){
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 接触链接
     * @param n
     * @return
     */
    E unlink(Node<E> n){
        final E element = n.item;
        final Node<E> next = n.next;
        final Node<E> prev = n.prev;
        if (Objects.isNull(prev)) {
            // n 为头结点
            first = next;
        } else {
            prev.next = next;
            n.prev = null;
        }

        if (Objects.isNull(next)) {
            // n 为尾节点
            last = prev;
        } else {
            next.prev = prev;
            n.next = null;
        }

        n.item = null;
        size--;
        return element;
    }

    @Override
    public E get(int index) {
        if (index > size) {
            throw new RuntimeException("link size out of rang!");
        }

        return node(index).item;
    }

    Node<E> node(int index) {
        Node<E> node;
        if (index < 0) {
            node = last;
            for (int i = 0; i > index; i--) {
                node = node.prev;
            }
        } else {
            node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        }

        return node;
    }

    @Override
    public void printLinkList() {

    }

    protected static class Node<E> {

        E item;
        Node<E> next;
        Node<E> prev;

        public Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }

    }

    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<String>("test001");

        linkedList.add("1");
        linkedList.add("2");
        linkedList.add("3");

        System.out.println(linkedList.get(0));
    }
}
